import React, { Fragment, useEffect, useState } from 'react';
import {
  Box,
  Empty,
  Grid,
  GridItem,
  Icon,
  LoadingPlaceholder,
  MainColorType,
  Menu,
  Text,
} from '@nova-hf/ui';
import { MenuItemProps } from '@nova-hf/ui/umd/ts/src/menu/MenuItem';
import { ErrorBanner } from 'beta/components/error/ErrorBanner';
import Authentication from 'beta/store/authentication';
import { formatDate, formatPrice, getMonths } from 'beta/utils/helpers';
import { useTranslation } from 'beta/utils/i18n';
import { endOfMonth, startOfMonth } from 'date-fns';
import { capitalize, uniq } from 'lodash';
import { inject } from 'mobx-react';
import { useForeignSummaryLazyQuery } from 'typings/graphql';

type ForeignSummaryProps = {
  color: MainColorType;
  authentication?: Authentication;
  phoneNumber: string;
};

const ForeignSummary = ({ color, authentication, phoneNumber }: ForeignSummaryProps) => {
  const { t } = useTranslation(['subscriptions', 'errors']);

  const [date, setDate] = useState(startOfMonth(new Date()));
  const [getSummaryItems, { data, loading, error }] = useForeignSummaryLazyQuery();

  useEffect(() => {
    fetchDataWithMonth();
  }, [date]);

  const fetchDataWithMonth = () => {
    const endOfMonthDate = endOfMonth(date);
    if (date && authentication?.accountInput.ssn) {
      getSummaryItems({
        variables: {
          input: {
            nationalId: authentication?.accountInput.ssn,
            phoneNumber,
            dateFrom: new Date(date),
            dateTo: new Date(endOfMonthDate),
          },
        },
      });
    }
  };

  const navigationDropdownItems = (): Omit<MenuItemProps, 'color'>[] => {
    const dateTime = date ? new Date(date) : new Date();
    const currDate = dateTime || new Date();

    return uniq(
      getMonths(new Date(), 5)
        .reverse()
        .map(({ month, date }: { month: string; date: Date }) => {
          return {
            text: capitalize(month),
            isActive: currDate.getMonth() === date.getMonth(),
            onClick: () => setDate(startOfMonth(date)),
          };
        }),
    );
  };

  const isNumeric = (value: string) => {
    return !isNaN(parseFloat(value)) && isFinite(parseFloat(value));
  };

  const calculateTotalSum = () => {
    const totalSum = data?.foreignSummary?.reduce(
      (total, group) => total + (group?.groupSum ?? 0),
      0,
    );
    return formatPrice(totalSum ?? 0);
  };

  return (
    <Box width="100%" marginY={20}>
      <Box
        display="flex"
        justifyContent="space-between"
        flexDirection="row"
        width="100%"
        marginY={[3, 6]}
      >
        <Text variant="h6">{t('foreignSummary.headerTitle')}</Text>
        <Menu
          color={color}
          disclosure={
            <Box
              display="inline-flex"
              alignItems="center"
              gap={1}
              renderAs="button"
              boxShadow={{ focusVisible: 'focused' }}
            >
              <Text variant="pMediumBold">{capitalize(formatDate(date, 'MMMM'))}</Text>
              <Icon icon="arrowDown" color={color} />
            </Box>
          }
          items={navigationDropdownItems()}
          label="select month"
        />
      </Box>
      {error || loading ? (
        <ErrorBanner
          eyebrowTexts={[
            t('errors:usageSummary.eyebrows.1'),
            t('errors:usageSummary.eyebrows.2'),
            t('errors:usageSummary.eyebrows.3'),
          ]}
          titles={[
            t('errors:usageSummary.titles.1'),
            t('errors:usageSummary.titles.2'),
            t('errors:usageSummary.titles.3'),
          ]}
          descriptions={[
            t('errors:usageSummary.descriptions.1'),
            t('errors:usageSummary.descriptions.2'),
            t('errors:usageSummary.descriptions.3'),
          ]}
          icon="zap"
          color="attention"
          showLoading={loading}
          refetchButton={{
            text: t('errors:buttons.refresh'),
            icon: 'refresh',
            onClick: () => fetchDataWithMonth(),
          }}
          loadingComponent={<LoadingForeignSummaryItems numberOfRows={3} />}
        />
      ) : data?.foreignSummary && !!data?.foreignSummary?.length ? (
        <Grid gridTemplate={{ sm: 6, md: 12 }} rowGap={{ sm: 2, lg: 3 }} columnGap={{ sm: 2 }}>
          <GridItem gridColumn={{ sm: 'span1', md: '1/4' }}>
            <Text variant="eyebrowMedium" color="grey400">
              {t('foreignSummary.date')}
            </Text>
          </GridItem>
          <GridItem gridColumn={{ sm: 'span2', md: '5/7' }}>
            <Text variant="eyebrowMedium" color="grey400">
              {t('foreignSummary.overview')}
            </Text>
          </GridItem>
          <GridItem gridColumn={{ sm: 'span2', md: '8/9' }}>
            <Text
              renderAs="p"
              variant="eyebrowMedium"
              color="grey400"
              textAlign={{ sm: 'right', md: 'right' }}
            >
              {t('foreignSummary.usage')}
            </Text>
          </GridItem>
          <GridItem gridColumn={{ sm: 'span1', md: '10/12' }}>
            <Text renderAs="p" variant="eyebrowMedium" color="grey400" textAlign="right">
              {t('foreignSummary.total')}
            </Text>
          </GridItem>
          <GridItem gridColumn={{ sm: 'span6', md: 'span12' }}>
            <Box style={{ height: '1px' }} backgroundColor="grey200"></Box>
          </GridItem>

          {data?.foreignSummary?.map((summaryGroup, i) => {
            return (
              <Fragment key={`${summaryGroup?.groupName}__${i}`}>
                <GridItem gridColumn={{ sm: 'span3', md: 'span6' }}>
                  <Text variant="pMediumBold">{summaryGroup?.groupName}</Text>
                </GridItem>
                <GridItem gridColumn={{ sm: 'span3', md: 'span6' }}>
                  <Text variant="pMediumBold" textAlign="right">
                    {formatPrice(summaryGroup?.groupSum ?? 0)}
                  </Text>
                </GridItem>
                {summaryGroup?.roamingUsageDetails?.filter(Boolean).map((summaryItem) => {
                  return (
                    <Fragment key={i}>
                      <GridItem data-key="date-column" gridColumn={{ sm: 'span1', md: '1/4' }}>
                        <Text variant="pMediumRegular">
                          {formatDate(summaryItem?.usageStart ?? '', 'dd.MM.yy')}
                        </Text>
                      </GridItem>
                      <GridItem data-key="overview-column" gridColumn={{ sm: 'span2', md: '5/7' }}>
                        <Text variant="pMediumRegular">
                          {isNumeric(summaryItem?.unit ?? '')
                            ? `${Math.ceil(parseFloat(summaryItem?.unit ?? ''))} ${
                                summaryItem?.packageUnit
                              }`
                            : summaryItem?.unit}
                        </Text>
                      </GridItem>
                      <GridItem data-key="usage-column" gridColumn={{ sm: 'span2', md: '8/9' }}>
                        <Text renderAs="p" variant="pMediumRegular" textAlign="right">
                          {`${Math.ceil(summaryItem?.billedQuantity ?? 0)} ${
                            summaryItem?.billedUnitOfMeasure
                          }`}
                        </Text>
                      </GridItem>
                      <GridItem
                        data-key="priceSum-column"
                        gridColumn={{ sm: 'span1', md: '10/12' }}
                      >
                        <Text renderAs="p" variant="pMediumRegular" textAlign="right">
                          {formatPrice(summaryItem?.fee ?? 0)}
                        </Text>
                      </GridItem>
                    </Fragment>
                  );
                })}
                <GridItem gridColumn={{ sm: 'span6', md: 'span12' }}>
                  <Box style={{ height: '1px' }} backgroundColor="grey200"></Box>
                </GridItem>
              </Fragment>
            );
          })}
          <GridItem gridColumn={{ sm: 'span3', md: 'span6' }}>
            <Text variant="pMediumBold">{t('foreignSummary.total')}</Text>
          </GridItem>
          <GridItem gridColumn={{ sm: 'span3', md: 'span6' }}>
            <Text variant="pMediumBold" textAlign="right">
              {calculateTotalSum()}
            </Text>
          </GridItem>
        </Grid>
      ) : (
        <Box marginY={20}>
          <Empty
            icon="binocular"
            color={color}
            title={t('foreignSummary.noSummaryTitle')}
            subtitle={t('foreignSummary.noSummaryDetails', {
              currentMonth: capitalize(formatDate(date, 'MMMM')),
            })}
          />
        </Box>
      )}
    </Box>
  );
};

export default inject('authentication')(ForeignSummary);

const LoadingForeignSummaryItems = ({ numberOfRows }: { numberOfRows: number }) => {
  return (
    <>
      {[...Array(numberOfRows)].map((_x, i) => (
        <GridItem key={i} gridColumn={{ sm: 'span2', md: 'span12' }}>
          <LoadingPlaceholder width="100%" height={3} />
        </GridItem>
      ))}
    </>
  );
};
